home *** CD-ROM | disk | FTP | other *** search
/ Atari Forever 4 / Atari Forever 4.zip / Atari Forever 4.iso / PD_THEMA / CPX / GEMSOUND / SOURCE / SND_CPX.C < prev    next >
C/C++ Source or Header  |  1998-03-14  |  18KB  |  519 lines

  1. /*  SND_CPX.C
  2.  *  Das CPX-Modul zur Steuerung von GEMSOUND.PRG
  3.  *
  4.  *  aus: GEM Sound
  5.  *       TOS Magazin
  6.  *
  7.  *  (c)1992 by Richard Kurz
  8.  *  Vogelherdbogen 62
  9.  *  7992 Tettnang
  10.  *  Fido 2:241/7232
  11.  *
  12.  *  Erstellt mit Pure C
  13.  */
  14.  
  15. #include <aes.h>
  16. #include <tos.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <stddef.h>
  21. #include <portab.h>
  22. #include "cpx.h"
  23. #include "sounds.h"
  24. #include "sndcpx.h"
  25. #pragma warn -rpt 
  26. #include "sndcpx.rsh"
  27. #pragma warn +rpt 
  28.  
  29.  
  30. /* Eine handvoll Prototypen */
  31. CPXINFO * cdecl cpx_init(XCPB *Xcpb);
  32. WORD cdecl cpx_call(GRECT *re); 
  33. void save_par(void);
  34. void ch_vtext(void);
  35. void do_ok(void);
  36. void init_dialog(void); 
  37. int handle_dialog(WORD button, WORD *msg);
  38. int do_cpx_alert(OBJECT *o,int e);
  39.  
  40. /* Globale Variablen */
  41. GRECT   *w_rect;        /* Die Koordinaten des Fensters.        */
  42. XCPB    *xcpb;          /* Zeiger auf die XControl-Funktionen.  */
  43. CPXINFO cpxinfo;        /* Zeiger auf unsere Funktionen für     */
  44.                         /* XControl.                            */
  45. MFORM   mzeiger;        /* Parkplatz für den Mauszeiger.        */
  46. char *items[MAX_SAMP];  /* Zeiger-Feld für die PopUp-Menüs.     */
  47. char so[MAX_SAMP][20];  /* Area für die Sound-Namen.            */
  48. char go[MAX_SAMP][20];  /* Area für die AES-Namen.              */
  49.  
  50. struct GPAR             /* Nummern und Namen der AES-Aufrufe.   */
  51. {
  52.     int nr;
  53.     char name[9];
  54. } gp[MAX_SAMP]=
  55. {
  56.     {0,  "LÖSCHEN"},
  57.     {-1, "SysBell"},
  58.     {-2, "T_Click"},
  59.     {30, "Menu_Bar"},
  60.     {33, "Menu_Tno"},
  61.     {50, "Form_Do"},
  62.     {51, "F_Dial"},
  63.     {52, "F_Alert"},
  64.     {53, "F_Error"},
  65.     {56, "F_Button"},
  66.     {70, "Graf_Rub"},
  67.     {71, "Graf_Dra"},
  68.     {72, "Graf_Mbo"},
  69.     {73, "Graf_Gro"},
  70.     {74, "Graf_Shr"},
  71.     {78, "Graf_Mou"},
  72.     {90, "Fsel_Inp"},
  73.     {91, "Fsel_ExI"},
  74.     {101,"W_Open"},
  75.     {102,"W_Close"}
  76. };
  77.  
  78. int vslide;             /* Wert für den vertikalen Slider.      */
  79. C_SOUNDS *si,           /* Zeiger auf die COOKIE-Struktur.      */
  80.          si_back;
  81.  
  82. OBJECT  *dialog,        /* Zeiger auf unsere Dialoge.           */
  83.         *info;
  84.         
  85. /* Externe Variablen aus dem Assemblerteil */
  86. extern struct 
  87. {
  88.     int r_flag;
  89.     int ruhe;
  90.     int nr[MAX_SAMP];
  91.     int sound[MAX_SAMP];
  92.     int an[MAX_SAMP];
  93. } sound_inf;
  94.  
  95. CPXINFO * cdecl cpx_init(XCPB *Xcpb)
  96. /* Diese Funktion wird während der XControl-Initialisierung und */
  97. /* bei jeder Aktivierung unseres CPX-Moduls als erstes          */
  98. /* gestartet. Sie erhält einen Zeiger auf die CPX-Funktionen    */
  99. /* und muß einen Zeiger auf die eigenen Funktionen oder NULL    */
  100. /* bzw. 1 zurückgeben.                                          */
  101. {
  102.     int i;
  103.     xcpb=Xcpb;
  104.     
  105.  
  106.     if(xcpb->booting)
  107.     /* Dieses Flag zeigt an, ob es der erste Aufruf (während der*/
  108.     /* XControl-Initialisierung) ist.                           */
  109.     {
  110.         /* Die gesicherten Werte werden gesetzt.                */
  111.         if((*xcpb->getcookie)('GSND',(long *)(&si)))
  112.         {
  113.             if(!si->fix)
  114.             {
  115.                 si->fix=TRUE;
  116.                 for(i=0;i<MAX_SAMP;i++)
  117.                 {
  118.                     si->gem_inf[i].nr=0;
  119.                     si->gem_inf[i].sound=0;
  120.                     si->gem_inf[i].an=0;
  121.                 }
  122.                 si->r_flag=sound_inf.r_flag;
  123.                 si->ruhe=sound_inf.ruhe;
  124.                 for(i=0;i<MAX_SAMP;i++)
  125.                 {
  126.                     if(sound_inf.sound[i] < si->max_sound)
  127.                     {
  128.                         si->gem_inf[i].nr=sound_inf.nr[i];
  129.                         si->gem_inf[i].sound=sound_inf.sound[i];
  130.                         si->gem_inf[i].an=sound_inf.an[i];
  131.                     }
  132.                 }   
  133.                 Supexec(si->set_vec);
  134.             }
  135.         }
  136.         /* Während der Initialisierung muß eine 1 zurückgegeben */
  137.         /* werden, wenn das CPX-Modul nicht set_only sein soll. */
  138.         return ((CPXINFO *)1);
  139.     }
  140.     if(!xcpb->SkipRshFix)
  141.     /* In diesem Flag wird festgehalten, ob der OBJECT-Baum     */
  142.     /* schon angepaßt wurde.                                    */
  143.     {
  144.         /* Wir passen den OBJECT-Baum an.                       */
  145.         (*xcpb->rsh_fix)(NUM_OBS,NUM_FRSTR,NUM_FRIMG,NUM_TREE,
  146.                          rs_object,rs_tedinfo,rs_strings,rs_iconblk,
  147.                          rs_bitblk,rs_frstr,rs_frimg,rs_trindex,
  148.                          rs_imdope);
  149.     }
  150.     dialog=(OBJECT *)rs_trindex[DIALOG];
  151.     info=(OBJECT *)rs_trindex[PINFO];
  152.  
  153.     /* In die CPXINFO-Struktur müssen unsere Funktionen ein-    */
  154.     /* getragen werden.                                         */
  155.     cpxinfo.cpx_call    =cpx_call;
  156.     cpxinfo.cpx_draw    =NULL;
  157.     cpxinfo.cpx_wmove   =NULL;
  158.     cpxinfo.cpx_timer   =NULL;
  159.     cpxinfo.cpx_key     =NULL;
  160.     cpxinfo.cpx_button  =NULL;
  161.     cpxinfo.cpx_m1      =NULL;
  162.     cpxinfo.cpx_m2      =NULL;
  163.     cpxinfo.cpx_hook    =NULL;
  164.     cpxinfo.cpx_close   =NULL;
  165.     
  166.     /* Mit der Rückgabe unserer Funktionen melden wir uns beim  */
  167.     /* XControl an.                                             */
  168.     return(&cpxinfo);
  169. } /* cpx_init */
  170.  
  171. WORD cdecl cpx_call(GRECT *rect)
  172. {
  173.     WORD msg[8];        /* Puffer für Xform_do.                 */
  174.     WORD button,        /* Welches Schweinderl ähh button.      */
  175.          ende;          /* Flag für's ENDE.                     */
  176.  
  177.     
  178.     if(!(*xcpb->getcookie)('GSND',(long *)(&si)))
  179.     {
  180.         form_alert(1,"[3][ |Sorry,|GEMSOUND.PRG fehlt][ Okay ]");
  181.         return(FALSE);
  182.     }
  183.     memcpy(&si_back,si,sizeof(si_back));
  184.  
  185.     /* Unser Dialog muß angepaßt werden.                        */
  186.     w_rect=rect;
  187.     dialog[ROOT].ob_x=w_rect->g_x;
  188.     dialog[ROOT].ob_y=w_rect->g_y;
  189.     
  190.     /* Initialisieren und zeichnen.                             */
  191.     init_dialog();
  192.     objc_draw(dialog,ROOT,MAX_DEPTH,
  193.                 w_rect->g_x,w_rect->g_y,w_rect->g_w,w_rect->g_h);
  194.     do
  195.     { 
  196.         /* Wir überlassen XControl die Verwaltung des Dialogs.  */
  197.         button=(*xcpb->Xform_do)(dialog,0,msg);
  198.         /* Nun müssen wir arbeiten.                             */
  199.         ende=handle_dialog(button,msg);
  200.     } while(!ende);
  201.     
  202.     /* Ende unseres Moduls, XControl ist wieder an der Reihe.   */
  203.     memcpy(si,&si_back,sizeof(si_back));
  204.     return(FALSE);
  205. } /* cpx_call */
  206.  
  207. WORD handle_dialog(WORD button, WORD *msg)
  208. /* Hier behandeln wir die Objekte, die angeklickt wurden.       */
  209. /* In button steht die Objekt-Nr. und in msg ein Zeiger auf     */
  210. /* einen Messag-Buffer (ähnlich wie evnt_mesag).                */
  211. {
  212.     GRECT r1;           /* Koordinaten-Feld.                    */
  213.     WORD i,p,ox,oy;     /* Hilfsvariablen.                      */
  214.     WORD mx,my,mk,kb;   /* Variablen für das Mäusekind.         */
  215.     
  216.     if((button!=-1)&&(button & 0x8000))
  217.         button &= 0x7fff;
  218.  
  219.     switch(button)
  220.     {
  221.         case M_INFO:
  222.             items[0]="  Info...       ";
  223.             
  224.             objc_offset(dialog,M_INFO,&r1.g_x,&r1.g_y);
  225.             r1.g_y+=17;
  226.             r1.g_w=dialog[M_INFO].ob_width;
  227.             r1.g_h=dialog[M_INFO].ob_height;
  228.             
  229.             p=(*xcpb->Popup)(items,1,-1,3,&r1,w_rect);
  230.             if(p==0) do_cpx_alert(info,0);
  231.  
  232.             dialog[button].ob_state &= ~SELECTED;
  233.             objc_draw(dialog,button,MAX_DEPTH,w_rect->g_x,w_rect->g_y,w_rect->g_w,w_rect->g_h);
  234.             break;
  235.  
  236.         case M_OPTION:
  237.             if(si->ruhe)
  238.                 items[0]="  Sounds Aus    ";
  239.             else
  240.                 items[0]="  Sounds Ein    ";
  241.             if(si->r_flag)
  242.                 items[1]="  SReset Ein    ";
  243.             else
  244.                 items[1]="  SReset Aus    ";
  245.             items[2]=    "  Sound spielen ";
  246.             
  247.             objc_offset(dialog,M_OPTION,&r1.g_x,&r1.g_y);
  248.             r1.g_y+=17;
  249.             r1.g_w=dialog[M_OPTION].ob_width;
  250.             r1.g_h=dialog[M_OPTION].ob_height;
  251.             
  252.             p=(*xcpb->Popup)(items,3,-1,3,&r1,w_rect);
  253.             if(p==0)
  254.                 si->ruhe=si->ruhe?0:1;
  255.             else if(p==1)
  256.                 si->r_flag=si->r_flag?0:1;
  257.             else if(p==2)
  258.             {
  259.                 for(i=0;i<si->max_sound;i++) items[i]=so[i];
  260.                 p=(*xcpb->Popup)(items,si->max_sound,-1,3,&r1,w_rect);
  261.                 if(p!=-1)
  262.                 {
  263.                     i=si->ruhe;
  264.                     si->ruhe=TRUE;
  265.                     si->play(&(si->sounds[p]),TRUE);
  266.                     si->ruhe=i;
  267.                 }
  268.             }
  269.             dialog[button].ob_state &= ~SELECTED;
  270.             objc_draw(dialog,button,MAX_DEPTH,w_rect->g_x,w_rect->g_y,w_rect->g_w,w_rect->g_h);
  271.             break;
  272.             
  273.         case VMINUS:
  274.             (*xcpb->Sl_arrow)(dialog,VVATER,VTEXT,button,-1,1,MAX_SAMP-3,&vslide,0,ch_vtext);
  275.             break;
  276.         case VPLUS:
  277.             (*xcpb->Sl_arrow)(dialog,VVATER,VTEXT,button,1,1,MAX_SAMP-3,&vslide,0,ch_vtext);
  278.             break;
  279.         case VVATER:
  280.             objc_offset(dialog,VTEXT,&ox,&oy);
  281.             graf_mkstate(&mx,&my,&mk,&kb);
  282.             p= my>oy ? -5 : 5;
  283.             (*xcpb->Sl_arrow)(dialog,VVATER,VTEXT,-1,p,1,MAX_SAMP-3,&vslide,0,ch_vtext);
  284.             break;
  285.         case VTEXT:
  286.             (*xcpb->MFsave)(MFSAVE, &mzeiger);
  287.             graf_mouse(FLAT_HAND,NULL);
  288.             (*xcpb->Sl_dragy)(dialog,VVATER,VTEXT,1,MAX_SAMP-3,&vslide,ch_vtext);
  289.             (*xcpb->MFsave)(MFRESTORE, &mzeiger);
  290.             break;
  291.  
  292.         case SICHERN:
  293.             /* Wer sich für's SICHERN interessiert, dem sei     */
  294.             /* save_par() empfohlen.                            */
  295.             save_par();
  296.             dialog[button].ob_state &= ~SELECTED;
  297.             objc_draw(dialog,button,1,
  298.                     w_rect->g_x,w_rect->g_y,w_rect->g_w,w_rect->g_h);
  299.             break;
  300.         case OKAY:
  301.             /* Bei OKAY werden noch die Betriebsparameter       */
  302.             /* gesichert                                        */
  303.             do_ok();
  304.         case ABBRUCH:
  305.             dialog[button].ob_state &= ~SELECTED;
  306.             return(TRUE);
  307.  
  308.         default:
  309.             if(button>=FLAG && button <=FLAG+3)
  310.             {
  311.                 items[0]="  An  ";
  312.                 items[1]="  Aus ";
  313.             
  314.                 objc_offset(dialog,button,&r1.g_x,&r1.g_y);
  315.                 r1.g_w=dialog[button].ob_width;
  316.                 r1.g_h=dialog[button].ob_height;
  317.                 i=MAX_SAMP-3-vslide+(button-FLAG);
  318.                 if(si->gem_inf[i].nr)
  319.                 {
  320.                     p=(*xcpb->Popup)(items,2,si->gem_inf[i].an ? 0:1,3,&r1,w_rect);
  321.                     if(p==0)
  322.                     {
  323.                         si->gem_inf[i].an=TRUE;
  324.                         dialog[button].ob_spec.tedinfo->te_ptext="An";
  325.                     }
  326.                     else if(p==1)
  327.                     {
  328.                         si->gem_inf[i].an=FALSE;
  329.                         dialog[button].ob_spec.tedinfo->te_ptext="Aus";
  330.                     }
  331.                     objc_draw(dialog,button,MAX_DEPTH,w_rect->g_x,w_rect->g_y,w_rect->g_w,w_rect->g_h);
  332.                 }
  333.             }
  334.             else if(button>=SOUND && button <=SOUND+3)
  335.             {
  336.                 objc_offset(dialog,button,&r1.g_x,&r1.g_y);
  337.                 r1.g_w=dialog[button].ob_width;
  338.                 r1.g_h=dialog[button].ob_height;
  339.                 for(i=0;i<si->max_sound;i++) items[i]=so[i];
  340.                 i=MAX_SAMP-3-vslide+(button-SOUND);
  341.                 if(si->gem_inf[i].nr)
  342.                 {
  343.                     p=(*xcpb->Popup)(items,si->max_sound,si->gem_inf[i].sound,3,&r1,w_rect);
  344.                     if(p!=-1)
  345.                     {
  346.                         si->gem_inf[i].sound=p;
  347.                         ch_vtext(); 
  348.                         objc_draw(dialog,button,MAX_DEPTH,w_rect->g_x,w_rect->g_y,w_rect->g_w,w_rect->g_h);
  349.                     }
  350.                 }
  351.             }
  352.             else if(button>=AES_NR && button <=AES_NR+3)
  353.             {
  354.                 objc_offset(dialog,button,&r1.g_x,&r1.g_y);
  355.                 r1.g_w=dialog[button].ob_width;
  356.                 r1.g_h=dialog[button].ob_height;
  357.                 for(i=0;i<MAX_SAMP && gp[i].name[0];i++)
  358.                 {   
  359.                     sprintf(go[i],"  %-8s ",gp[i].name);
  360.                     items[i]=go[i];
  361.                 }
  362.                 p=(*xcpb->Popup)(items,i,-1,3,&r1,w_rect);
  363.                 i=MAX_SAMP-3-vslide+(button-AES_NR);
  364.                 if(p!=-1)
  365.                 {
  366.                     si->gem_inf[i].nr=gp[p].nr;
  367.                     ch_vtext(); 
  368.                     objc_draw(dialog,button,MAX_DEPTH,w_rect->g_x,w_rect->g_y,w_rect->g_w,w_rect->g_h);
  369.                 }
  370.             }
  371.             else if(button==-1)
  372.             {
  373.                 switch(msg[0])
  374.                 {
  375.                     case WM_CLOSED:
  376.                     /* Wurde das Fenster geschlossen, wird das  */
  377.                     /* wie OKAY behandelt.                      */
  378.                         do_ok();
  379.                     case AC_CLOSE:
  380.                     /* Bei AC_CLOSE nichts wie raus! Wurde vom  */
  381.                     /* Modul Speicher angefordert oder sind     */
  382.                     /* Dateien geöffnet, unbedingt aufräumen!!  */
  383.                         return(TRUE);
  384.                     case CT_KEY:
  385.                     /* Jemand hat eine Sondertaste gedrückt.    */
  386.                     /* Help, Undo, Funktions-Tasten usw.        */
  387.                         if(msg[3]==0x6200)      /* Help         */
  388.                         {
  389.                             form_alert(1,"[0][Hiiiiilfe !!!! ][ Ah ja ]");
  390.                         }
  391.                         else if(msg[3]==0x6100) /* Undo         */
  392.                         {
  393.                             p=form_alert(2,"[2][Undo oder nicht Undo|ist hier die Frage][ Ja | Nein ]");                            
  394.                             if(p==1)
  395.                             {
  396.                                 memcpy(si,&si_back,sizeof(si_back));
  397.                                 ch_vtext();
  398.                             }
  399.                         }
  400.                     default:
  401.                         break;
  402.                 }
  403.             }
  404.             break;
  405.     }
  406.     return(FALSE);
  407. } /* handle_dialog */
  408.  
  409. void init_dialog(void)
  410. /* Der Dialog wird aufgebaut                                    */
  411. {
  412.     int i;
  413.     vslide=MAX_SAMP-3;
  414.     (*xcpb->Sl_size)(dialog,VVATER,VTEXT,MAX_SAMP-3,4,0,16);
  415.     (*xcpb->Sl_y)(dialog,VVATER,VTEXT,vslide,1,MAX_SAMP-3,ch_vtext);
  416.     for(i=0;i<si->max_sound;i++)
  417.         sprintf(so[i],"  %-8s ",si->sounds[i].name);
  418. } /* init_dialog */
  419.  
  420. void save_par(void)
  421. /* Die Parameter werden von XControl an den Anfang des Daten-   */
  422. /* segments gesichert. Bitte den Assemblerteil anschauen!       */
  423. {
  424.     int i;
  425.     
  426.     if((*xcpb->XGen_Alert)(SAVE_DEFAULTS))
  427.     {
  428.         sound_inf.r_flag=si->r_flag;
  429.         sound_inf.ruhe=si->ruhe;
  430.         for(i=0;i<MAX_SAMP;i++)
  431.         {
  432.             sound_inf.nr[i]=si->gem_inf[i].nr;
  433.             sound_inf.sound[i]=si->gem_inf[i].sound;
  434.             sound_inf.an[i]=si->gem_inf[i].an;
  435.         }   
  436.         if(!(*xcpb->CPX_Save)(&sound_inf,sizeof(sound_inf)))
  437.             (*xcpb->XGen_Alert)(FILE_ERR);
  438.     }
  439. } /* save_par */
  440.  
  441. void ch_vtext(void)
  442. /* ONLINE Slider   */
  443. {
  444.     int i,p,sp;
  445.  
  446.     sp=MAX_SAMP-3-vslide;
  447.     for(i=0;(i<4) && (i+sp < MAX_SAMP);i++)
  448.     {
  449.         if(si->gem_inf[i+sp].nr)
  450.         {
  451.             for(p=0;p<MAX_SAMP;p++)
  452.             {
  453.                 if(gp[p].nr==si->gem_inf[i+sp].nr)
  454.                 {
  455.                     strncpy(dialog[AES_NR+i].ob_spec.tedinfo->te_ptext,gp[p].name,8);
  456.                     break;
  457.                 }
  458.             }
  459.             if(p>=MAX_SAMP)
  460.                 itoa(si->gem_inf[i+sp].nr,dialog[AES_NR+i].ob_spec.tedinfo->te_ptext,10);
  461.             strcpy(dialog[SOUND+i].ob_spec.tedinfo->te_ptext,si->sounds[si->gem_inf[i+sp].sound].name);
  462.             if(si->gem_inf[i+sp].an)
  463.                 dialog[FLAG+i].ob_spec.tedinfo->te_ptext="An";
  464.             else
  465.                 dialog[FLAG+i].ob_spec.tedinfo->te_ptext="Aus";
  466.         }
  467.         else
  468.         {
  469.             dialog[AES_NR+i].ob_spec.tedinfo->te_ptext[0]=0;
  470.             dialog[SOUND+i].ob_spec.tedinfo->te_ptext[0]=0;
  471.             dialog[FLAG+i].ob_spec.tedinfo->te_ptext="";
  472.         }
  473.     }
  474.     objc_draw(dialog,DISPLAY,MAX_DEPTH,
  475.                 w_rect->g_x,w_rect->g_y,w_rect->g_w,w_rect->g_h);
  476. } /* ch_vtext */
  477.  
  478. void do_ok(void)
  479. {
  480.     memcpy(&si_back,si,sizeof(si_back));
  481. } /* do_ok */
  482.  
  483. int do_cpx_alert(OBJECT *o,int e)
  484. /* ALARM! ALARM!                                                */
  485. /* Diese Funktion zeichnet und verwaltet eine Dialogbox im      */
  486. /* XControl-Fenster                                             */
  487. {
  488.     int i,ox,oy,
  489.         x,y,w,h;
  490.     static MFORM mf;
  491.     
  492.     wind_update(BEG_MCTRL);
  493.     wind_update(BEG_UPDATE);
  494.     (*xcpb->MFsave)(MFSAVE, &mf);
  495.     graf_mouse(ARROW,NULL);
  496.  
  497.     form_center(o,&x,&y,&w,&h); 
  498.     ox=o[ROOT].ob_x-x;
  499.     oy=o[ROOT].ob_y-y;
  500.     x=w_rect->g_x+((w_rect->g_w-w)/2);
  501.     y=w_rect->g_y+((w_rect->g_h-h)/2);
  502.     o[ROOT].ob_x=x+ox;
  503.     o[ROOT].ob_y=y+oy;
  504.  
  505.     form_dial(FMD_START,0,0,0,0,x,y,w,h);
  506.     form_dial(FMD_GROW,0,0,0,0,x,y,w,h);
  507.     objc_draw(o,ROOT,MAX_DEPTH,x,y,w,h);
  508.     i=form_do(o,e) & 0x7fff;
  509.     o[i].ob_state &= ~SELECTED;
  510.     form_dial(FMD_SHRINK,0,0,0,0,x,y,w,h);
  511.     form_dial(FMD_FINISH,0,0,0,0,x,y,w,h);
  512.  
  513.     (*xcpb->MFsave)(MFRESTORE, &mf);
  514.     wind_update(END_UPDATE);
  515.     wind_update(END_MCTRL);
  516.  
  517.     return(i);
  518. } /* do_cpx_alert */
  519.